﻿using DataCollection.ChangeCode;
using DataCollection.Config;
using DataCollection.ConnectionManage;
using DataCollection.Manage;
using DataCollection.SimulateTool;
using RQX.Common.Core.Config;
using RQX.Common.Core.Extension;
using RQX.Common.Core.File;
using RQX.Common.Core.Hardware.BaseCollection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DataCollection
{
    public partial class MainForm : Form
    {
        public ConnManage connManage = new ConnManage();

        public MainForm()
        {
            InitializeComponent();
        }
        private void FConsole_Load(object sender, EventArgs e)
        {
            try
            {
                menu_version.Text = $"程序版本：{Version.CurrentVersion}";
                //l_version.Text = Version.CurrentVersion;

                //加载列表数据
                this.LoadList();


                BeginShow();
                if (LocalConfig.info.NotifyIconRun) this.WindowState = FormWindowState.Minimized;
                if (LocalConfig.info.AutoRunPlug) tbtStartup_Click(null, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show("初始化错误:\r\n" + ex.Message.ToString());
            }
        }
        /// <summary>
        /// 设备管理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_device_manage_Click(object sender, EventArgs e)
        {
            DeviceManage manage = new DeviceManage();
            //this.Hide();
            if (manage.ShowDialog() == DialogResult.Cancel)
            {
                LoadList();
                //this.Show();
            }
        }

        private void BeginShow()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    if (txt_real_time_msg.Text.Length > 20000)
                    {
                        txt_real_time_msg.Text = txt_real_time_msg.Text.Substring(0, 5000);
                    }
                    while (queueMsg.TryDequeue(out var msg))
                    {
                        txt_real_time_msg.Text = msg + txt_real_time_msg.Text;
                    }
                    Thread.Sleep(1000);
                }
            });
        }
        //加载设备列表
        private void LoadList()
        {
            grid.Rows.Clear();
            var list = DeviceInfo.list;
            list.ForEach(item =>
            {
                var param = "";
                switch (item.ProType)
                {
                    case ProType.UDP:
                        param = item.UDP.GetParamStr();
                        break;
                    case ProType.TCPClient:
                        param = item.TCPClient.GetParamStr();
                        break;
                    case ProType.TCPServer:
                        param = item.TCPServer.GetParamStr();
                        break;
                    case ProType.COM:
                        param = item.COM.GetParamStr();
                        break;
                }
                grid.Rows.Add(item.GUID, item.DeviceName, item.ProType, item.PlugName, param, "未连接");
            });
        }

        private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (this.grid.Columns[e.ColumnIndex].Name == "dgv_control" && e.RowIndex >= 0)
            {
                DataGridViewRow dr = grid.Rows[e.RowIndex];
                string vsGuid = dr.Cells["dgv_guid"].Value.ToString();
                Enum.TryParse(dr.Cells["dgv_protocol_type"].Value.ToString(), out ProType Protocol);
                if (grid.Rows[e.RowIndex].Cells["dgv_status"].Value.ToString().Equals("未连接"))
                {
                    var info = DeviceInfo.list.Where(k => k.GUID.Equals(vsGuid)).FirstOrDefault();
                    if (info == null)
                    {
                        Task.Run(() =>
                        {
                            Thread.CurrentThread.IsBackground = false;
                            MessageBox.Show("启动失败！没有找到该插件!");
                        });
                        return;
                    }
                    var localIP = ConfigUtils.GetConfigurationRoot().GetSection("LocalConfig").GetValue("Name");
                    var startFlag = true;
                    try
                    {
                        switch (Protocol)
                        {
                            case ProType.TCPClient://客户端模式
                                startFlag = connManage.Connect(ShowRealTimeMsg, localIP, info);
                                break;
                            case ProType.TCPServer://服务端模式
                                connManage.StartService(ShowRealTimeMsg, localIP, info);
                                break;
                            case ProType.UDP:
                                startFlag = connManage.Connect(ShowRealTimeMsg, localIP, info);
                                break;
                            case ProType.COM:
                                startFlag = connManage.ConnectCom(ShowRealTimeMsg, localIP, info);
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        FormUtils.ShowMsg(ex.ToString());
                        startFlag = false;
                    }
                    if (startFlag)
                    {
                        var cell = grid.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell;
                        cell.Value = "停止服务";
                        grid.Rows[e.RowIndex].Cells["dgv_status"].Value = "已连接";
                    }
                }
                else
                {   //停止服务
                    if (MessageBox.Show("请确认要停止此设备的服务吗?", "询问:", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                        return;
                    //停止COM
                    Stop(dr.Cells["dgv_guid"].Value.ToString());
                    var cell = grid.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell;
                    cell.Value = "启动服务";
                    grid.Rows[e.RowIndex].Cells["dgv_status"].Value = "未连接";

                }
            }
        }
        private ConcurrentQueue<string> queueMsg = new ConcurrentQueue<string>();
        public void ShowRealTimeMsg(string msg)
        {
            if (msg.Length > 200)
            {
                msg = msg.Substring(0, 200);
            }
            queueMsg.Enqueue($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}  {msg}\n");
        }
        public void Stop(string guid)
        {
            ConnInfo conn = connManage.dicConnInfo[guid];
            switch (conn.ProType)
            {
                case ProType.UDP:
                    FormUtils.TryMethod(() => conn.udpClient?.Close());
                    break;
                case ProType.TCPClient:
                    FormUtils.TryMethod(() => conn.tcpClient?.Close());
                    break;
                case ProType.TCPServer:
                    FormUtils.TryMethod(() => conn.tcpServer?.Close());
                    break;
                case ProType.COM:
                    FormUtils.TryMethod(() => conn.myCom?.Close());
                    break;
            }
            connManage.dicConnInfo.Remove(guid);
        }
        //启动所有服务
        private void tbtStartup_Click(object sender, EventArgs e)
        {
            var count = this.grid.Rows.Count;
            var index = grid.Columns.IndexOf(grid.Columns["dgv_control"]);
            for (var i = 0; i < count; i++)
            {
                this.grid_CellContentClick(null, new DataGridViewCellEventArgs(index, i));
            }
        }
        //停止所有服务
        private void tbtStop_Click(object sender, EventArgs e)
        {
            MessageBox.Show("请通过列表逐个停止，批量停止功能暂停使用！");
            return;
        }
        #region Log
        private void tabControl1_Click(object sender, EventArgs e)
        {
            var tabName = tab.SelectedTab.Text;
            if (tabName.Equals("错误日志"))
            {
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "错误日志");
                FileUtils.CheckOrCreateDirPath(path);
                ImageList list = new ImageList();
                SetTreeNoByFilePath(tv_errorlog, path, "错误日志", list);
            }
            else if (tabName.Equals("调试日志"))
            {
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "调试日志");
                FileUtils.CheckOrCreateDirPath(path);
                ImageList list = new ImageList();
                SetTreeNoByFilePath(tv_debuglog, path, "调试日志", list);
            }
        }

        #region  treeview 绑定文件夹和文件

        /// <summary>
        /// 根据文件夹绑定到树
        /// </summary>
        /// <param name="treeview"></param>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        public bool SetTreeNoByFilePath(TreeView treeview, string FilePath, string BaseDirName, ImageList imgs)
        {
            treeview.Nodes.Clear();
            treeview.NodeMouseDoubleClick += (s, e) =>
            {
                var node = ((TreeView)s).SelectedNode;
                if (node.Name.StartsWith("dir_"))
                {
                    //Process.Start("explorer.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, node.FullPath));
                }
                else if (node.Name.StartsWith("file_"))
                {
                    Process.Start("notepad.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, node.FullPath));
                }
            };
            //treeview.ImageList = imgs;
            try
            {
                TreeNode parentNode = new TreeNode
                {
                    Text = BaseDirName,
                    Name = $"dir_{Text}",
                    Tag = FilePath,
                };
                parentNode.Expand();
                foreach (DirectoryInfo direc in new DirectoryInfo(FilePath).GetDirectories())
                {
                    TreeNode tn = new TreeNode
                    {
                        Text = direc.Name,
                        Name = $"dir_{Text}",
                        Tag = direc.FullName
                    };
                    //SetTreeNodeIco(tn, "dir", imgs);
                    SetSubDirectoryTreenode(direc, tn, imgs);
                    parentNode.Nodes.Add(tn);
                }
                foreach (FileInfo finfo in new DirectoryInfo(FilePath).GetFiles())
                {
                    TreeNode temptreenode = new TreeNode()
                    {
                        Tag = finfo.FullName,
                        Name = $"file_{Text}",
                        Text = finfo.Name
                    };
                    //SetTreeNodeIco(temptreenode, finfo.Extension, imgs);
                    parentNode.Nodes.Add(temptreenode);
                }
                treeview.Nodes.Add(parentNode);
                return true;
            }
            catch
            {
                return false;
            }

        }
        /// <summary>
        /// 设置子目录的
        /// </summary>
        /// <param name="direc">目录路径</param>
        /// <param name="tn"></param>
        /// <param name="imglist"></param>
        private void SetSubDirectoryTreenode(DirectoryInfo direc, TreeNode tn, ImageList imglist)
        {
            var currentTime = DateTime.Now.ToString("yyyyMMddHH");
            var currentLogFileName = $"{currentTime}.log";
            foreach (DirectoryInfo dir in new DirectoryInfo(direc.FullName).GetDirectories())
            {
                TreeNode temptn = new TreeNode(dir.Name)
                {
                    Text = dir.Name,
                    Name = $"dir_{Text}",
                    Tag = dir.FullName,
                };
                //SetTreeNodeIco(temptn, "dir", imglist);
                tn.Nodes.Add(temptn);
                foreach (FileInfo fileinfo in new DirectoryInfo(dir.FullName).GetFiles())
                {
                    TreeNode temptreenode = new TreeNode(fileinfo.Name)
                    {
                        Text = fileinfo.Name,
                        Name = $"file_{Text}",
                        Tag = fileinfo.FullName,
                    };
                    temptn.Nodes.Add(temptreenode);
                    if (temptreenode.Text.Equals(currentLogFileName))
                    {
                        var p = temptreenode.Parent;
                        while (p != null)
                        {
                            p.Expand();
                            p = p.Parent;
                        }
                    }
                    //SetTreeNodeIco(temptreenode, fileinfo.Extension, imglist);

                }
                SetSubDirectoryTreenode(dir, temptn, imglist);
            }
        }

        ///// <summary>
        ///// 为treeview设置小图标
        ///// </summary>
        ///// <param name="tn"></param>
        ///// <param name="strExt"></param>
        ///// <param name="imgs"></param>
        //private void SetTreeNodeIco(TreeNode tn, string strExt, ImageList imgs)
        //{
        //    string ext = strExt.Replace(".", "");
        //    if (ext.ToLower() == "dir")
        //    {
        //        tn.ImageIndex = imgs.Images.IndexOfKey("close");
        //        tn.SelectedImageIndex = imgs.Images.IndexOfKey("open");
        //    }
        //    else if (ext.ToLower() == "doc" || ext.ToLower() == "rar" || ext.ToLower() == "txt")
        //    {
        //        tn.ImageIndex = imgs.Images.IndexOfKey(ext);
        //        tn.SelectedImageIndex = imgs.Images.IndexOfKey(ext);
        //    }
        //    else
        //    {
        //        tn.ImageIndex = imgs.Images.IndexOfKey("other");
        //        tn.SelectedImageIndex = imgs.Images.IndexOfKey("other");
        //    }
        //}

        #endregion

        private void tv_errorlog_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var node = tv_errorlog.SelectedNode;
            if (node.Name.StartsWith("file_"))
            {
                try
                {
                    Task.Run(() =>
                    {
                        string msg = "";
                        List<string> list = new List<string>();
                        using (StreamReader sr = new StreamReader(node.Tag.ToString()))
                        {
                            msg = sr.ReadLine();
                            while (msg.IsNotNull())
                            {
                                list.Add(msg);
                                msg = sr.ReadLine();
                            }
                        }
                        list.RemoveRange(0, Math.Max(0, list.Count - 200));
                        msg = "";
                        list.ForEach(str => msg += $"{str}\n");
                        rtxt_errorlog.Invoke(new Action(() =>
                        {
                            rtxt_errorlog.Text = msg;
                        }));
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

            }
        }

        private void tv_debuglog_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var node = tv_debuglog.SelectedNode;
            if (node.Name.StartsWith("file_"))
            {
                try
                {
                    Task.Run(() =>
                    {
                        string msg = "";
                        List<string> list = new List<string>();
                        using (StreamReader sr = new StreamReader(node.Tag.ToString()))
                        {
                            msg = sr.ReadLine();
                            while (msg.IsNotNull())
                            {
                                list.Add(msg);
                                msg = sr.ReadLine();
                            }
                        }
                        list.RemoveRange(0, Math.Max(0, list.Count - 200));
                        msg = "";
                        list.ForEach(str => msg += $"{str}\n");
                        rtxt_debuglog.Invoke(new Action(() =>
                        {
                            rtxt_debuglog.Text = msg;
                        }));
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

            }
        }
        #endregion

        #region 托盘相关
        /// <summary>
        /// 窗体关闭时，进入托盘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FConsole_FormClosing(object sender, FormClosingEventArgs e)
        {
            //注意判断关闭事件Reason来源于窗体按钮，否则用菜单退出时无法退出!
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;    //取消"关闭窗口"事件
                this.WindowState = FormWindowState.Minimized;    //使关闭时窗口向右下角缩小的效果
                this.Hide();
                return;
            }
        }
        /// <summary>
        /// 最小化时进入托盘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FConsole_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)    //最小化到系统托盘
            {
                notify_icon.Visible = true;    //显示托盘图标
                this.Hide();    //隐藏窗口
            }
        }
        /// <summary>
        /// 点击托盘打开界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void notify_icon_DoubleClick(object sender, EventArgs e)
        {
            //notify_icon.Visible = false;
            this.Show();
            WindowState = FormWindowState.Normal;
            this.Focus();
        }
        /// <summary>
        /// 托盘菜单右键退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_notify_icon_exit_Click(object sender, EventArgs e)
        {
            // 关闭所有的线程
            this.Dispose();
            this.Close();
        }
        #endregion
        /// <summary>
        /// 对码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_change_code_Click(object sender, EventArgs e)
        {
            CodeManage codeManage = new CodeManage();
            codeManage.ShowDialog();
        }
        /// <summary>
        /// 设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_setting_local_Click(object sender, EventArgs e)
        {
            ConfigSetting fConfigureLocalIP = new ConfigSetting();
            fConfigureLocalIP.ShowDialog();
        }
        /// <summary>
        /// 数据库设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_setting_db_Click(object sender, EventArgs e)
        {
            DbSetting setting = new DbSetting();
            setting.ShowDialog();
        }
        /// <summary>
        /// 模拟采集工具
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_tools_simulate_Click(object sender, EventArgs e)
        {
            Simulate simulate = new Simulate();
            this.Hide();
            if (simulate.ShowDialog() == DialogResult.Cancel)
            {
                this.Show();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menu_version_Click(object sender, EventArgs e)
        {
            Version.Show();
        }
    }
}